package skill

import (
	"encoding/json"
	//"sanguo/node/node_game"
	"sanguo/node/common/GlobalConstData"
	table_Skill "sanguo/node/table/excel/table/Skill"
	table_SkillLevel "sanguo/node/table/excel/table/SkillLevel"
	cs_message "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

type Skill struct {
	SkillID     int32 //技能ID
	Level       int32 //技能等级
	SpecialStar int32 //特性技能星级
}

type SkillPair struct {
	SkillType         int32
	Skill1            int32
	Skill2            int32
	CurrentSkillPoint int32
	TotalSkillPoint   int32
	Skills            map[int32]*Skill //当前类型的技能
}

type RoleSkill struct {
	skillPairs map[int32]*SkillPair //key 为武器类型
	skillDirty map[int32]bool
	dbDirty    bool
}

func FuncNewSkill() map[int32]*SkillPair {
	ret := map[int32]*SkillPair{}
	for i := int32(1); i <= GlobalConstData.WeaponTypeCount; i++ {
		ret[i] = newSkill(i)
	}
	return ret
}

func newSkill(typeID int32) *SkillPair {
	return &SkillPair{
		SkillType:         typeID,
		Skill1:            0,
		Skill2:            0,
		TotalSkillPoint:   0,
		CurrentSkillPoint: 0,
		Skills:            map[int32]*Skill{},
	}
}

//校验表数据
func (this *RoleSkill) CheckRoleSkill() {
	for i := int32(1); i < GlobalConstData.WeaponTypeCount; i++ {
		if this.skillPairs[i] == nil {
			this.skillPairs[i] = newSkill(i)
		}
	}
}

func (this *RoleSkill) GetSkill(skillType, skillID int32) *Skill {
	return this.skillPairs[skillType].Skills[skillID]
}

func (this *RoleSkill) GetRoleSkill(skillType int32) *SkillPair {
	return this.skillPairs[skillType]
}

func (this *RoleSkill) AddSkillPoint(power int32) {
	for _, rk := range this.skillPairs {
		rk.TotalSkillPoint += GlobalConstData.AddSkillPoint * power
		rk.CurrentSkillPoint += GlobalConstData.AddSkillPoint * power
		this.skillDirty[rk.SkillType] = true
	}
}

//重置技能点
func (this *RoleSkill) ResetSkillPoint(skillType int32) {
	rk := this.skillPairs[skillType]
	rk.CurrentSkillPoint = rk.TotalSkillPoint
	for _, skill := range rk.Skills {
		skill.Level = 1
	}

	this.skillDirty[rk.SkillType] = true
}

func (this *RoleSkill) CheckSkill(skillType, skillID int32) bool {
	if this.skillPairs[skillType] == nil {
		return false
	}
	if this.skillPairs[skillType].Skills[skillID] == nil {
		return false
	}

	return true
}

func (this *RoleSkill) LevelUp(skillType, skillID int32) bool {
	rk := this.skillPairs[skillType]
	skill := this.skillPairs[skillType].Skills[skillID]

	slDef := table_SkillLevel.Table_.IDMap[skill.Level]
	if rk.CurrentSkillPoint < slDef.CostSkillPoint {
		return false
	}

	skill.Level++
	rk.CurrentSkillPoint -= slDef.CostSkillPoint

	this.skillDirty[skillType] = true
	return true
}

func (this *RoleSkill) UnlockSkill(skillType, skillID, roleLevel int32) bool {
	SkillDef := table_Skill.Table_.IDMap[skillID]
	if SkillDef == nil {
		return false
	}

	if this.skillPairs[skillType] == nil {
		return false
	}
	if this.skillPairs[skillType].Skills[skillID] != nil {
		return false
	}

	if roleLevel < SkillDef.UnLockLevel {
		return false
	}

	sk := &Skill{
		SkillID:     skillID,
		Level:       1,
		SpecialStar: int32(0),
	}

	this.skillPairs[skillType].Skills[skillID] = sk
	this.skillDirty[skillType] = true

	return true

}

func (this *RoleSkill) SetSkill(skillType, skillID, pos int32) {

	if pos == 1 {
		this.skillPairs[skillType].Skill1 = skillID
	} else if pos == 2 {
		this.skillPairs[skillType].Skill2 = skillID
	}

	this.skillDirty[skillType] = true

}

//打包所有属性，不改变dirty标记
func (this *RoleSkill) PackSkill() []*cs_message.RoleSkill {
	ret := []*cs_message.RoleSkill{}
	for _, v := range this.skillPairs {
		rk := &cs_message.RoleSkill{
			SkillType:  proto.Int32(v.SkillType),
			Skill1:     proto.Int32(v.Skill1),
			Skill2:     proto.Int32(v.Skill2),
			SkillPoint: proto.Int32(v.CurrentSkillPoint),
		}
		for _, sk := range v.Skills {

			sk_ := &cs_message.Skill{
				SkillID:     proto.Int32(sk.SkillID),
				Level:       proto.Int32(sk.Level),
				SpecialStar: proto.Int32(sk.SpecialStar),
			}
			rk.Skills = append(rk.Skills, sk_)
		}
		ret = append(ret, rk)
	}
	return ret
}

//
func (this *RoleSkill) GetDrityLenght() int {
	return len(this.skillDirty)
}

//打包dirty属性并清除dirty标记
func (this *RoleSkill) PackSkillModify() []*cs_message.RoleSkill {
	ret := []*cs_message.RoleSkill{}
	for id, b := range this.skillDirty {
		if b {
			v := this.skillPairs[id]
			delete(this.skillPairs, id)
			rk := &cs_message.RoleSkill{
				SkillType:  proto.Int32(v.SkillType),
				Skill1:     proto.Int32(v.Skill1),
				Skill2:     proto.Int32(v.Skill2),
				SkillPoint: proto.Int32(v.CurrentSkillPoint),
			}
			for _, sk := range v.Skills {

				sk_ := &cs_message.Skill{
					SkillID:     proto.Int32(sk.SkillID),
					Level:       proto.Int32(sk.Level),
					SpecialStar: proto.Int32(sk.SpecialStar),
				}
				rk.Skills = append(rk.Skills, sk_)
			}
			ret = append(ret, rk)
		}
	}
	return ret
}

/****************************************/

func (this *RoleSkill) PackJson(fields map[string]interface{}) {
	if this.dbDirty {
		jsonStr, err := json.Marshal(this.skillPairs)
		if nil == err {
			fields["skill"] = jsonStr
		}
	}
}

func (this *RoleSkill) IsDirty() bool {
	return this.dbDirty
}

func (this *RoleSkill) SetDirtyFlag() {
	this.dbDirty = true
}

func (this *RoleSkill) ClearDirtyFlag() {
	this.dbDirty = false
}

func (this *RoleSkill) Init(skillPairs map[int32]*SkillPair) {
	this.skillPairs = skillPairs
	this.skillDirty = map[int32]bool{}
	this.dbDirty = false
}
